<?php

namespace app\api\biz;

use app\common\biz\Biz;
use app\common\biz\list\Lists;
use app\common\biz\list\Search;
use app\common\Cache;
use app\common\enum\Cache as CacheEnum;
use app\common\enum\Code;
use app\common\enum\SearchType;
use app\common\model\biz\SysUser;
use app\common\model\biz\SysUserLogLogin;
use app\common\Result;
use Exception;
use think\db\exception\DbException;

class UserBiz extends Biz
{

    public static function list(array $searchParams = []): UserBiz
    {
        $searchType = new \app\common\biz\list\SearchType();
        $searchType->set('name', SearchType::Like);

        $search = new Search($searchParams, $searchType);
        $search->setField('id,name,account,status,avatar,memo,create_time,update_time');
        $search->setParams('id', 1, SearchType::NE);

        $lists = new Lists(new SysUser(), $search);
        return self::success($lists->data());
    }

    public static function detail(int $id): UserBiz
    {
        $user = SysUser::field('id,name,account,status,avatar,memo,create_time,update_time')->find($id);
        return self::success($user);
    }

    public static function add(array $data): UserBiz
    {
        try {
            $user = SysUser::where('account', $data['account'])
                ->whereNull('delete_time')
                ->findOrEmpty();
            if (!$user->isEmpty()) {
                return self::error('此账号已存在！');
            }

            $data['password'] = SysUser::encryptPassword($data['password']);
            $user = SysUser::create($data);
            unset($user->password);
            return self::success($user);
        } catch (DbException $e) {
            Result::dbException($e->getData());
        } catch (Exception $e) {
            Result::httpException($e->getMessage());
        }
    }

    public static function edit(array $data): UserBiz
    {
        if (!isset($data['id']) || 1 === $data['id']) {
            return self::errorByCode(Code::ParamsInvalid);
        }

        try {
            $user = SysUser::findOrEmpty($data['id']);
            if ($user->isEmpty()) {
                return self::errorByCode(Code::DataNotFound);
            }

            $isOk = $user->save($data);
            return self::success($isOk);
        } catch (DbException $e) {
            Result::dbException($e->getData());
        } catch (Exception $e) {
            Result::httpException($e->getMessage());
        }
    }

    public static function del(string|array $ids): UserBiz
    {
        $users = SysUser::whereIn('id', $ids)
            ->where('id', '<>', 1)
            ->select();
        if ($users->isEmpty()) {
            return self::errorByCode(Code::DataNotFound);
        }

        foreach ($users as $user) {
            $user->delete();
        }

        return self::success();
    }

    public static function setPassword(string $oldPassword, string $newPassword): UserBiz
    {
        $uid = Cache::get(CacheEnum::UID);
        if (empty($uid)) {
            return self::error('请重新登录！');
        }

        $user = SysUser::findOrEmpty($uid);
        if ($user->isEmpty()) {
            return self::errorByCode(Code::DataNotFound);
        }

        if ($user->password !== SysUser::encryptPassword($oldPassword)) {
            return self::error('原密码错误！');
        }

        $user->password = SysUser::encryptPassword($newPassword);
        $isOk = $user->save();
        return self::success($isOk);
    }

    public static function setUserPassword(int $uid, string $password): UserBiz
    {
        $user = SysUser::findOrEmpty($uid);
        if ($user->isEmpty()) {
            return self::errorByCode(Code::DataNotFound);
        }

        $user->password = SysUser::encryptPassword($password);
        $isOk = $user->save();
        return self::success($isOk);
    }

    public static function login(string $account, string $password): UserBiz
    {
        $user = SysUser::where('account', $account)->whereNull('delete_time')->findOrEmpty();
        if ($user->isEmpty()) {
            SysUserLogLogin::add("账号有误:{$account}|{$password}");
            return self::error('账号或密码有误！');
        }

        if ($user->password !== SysUser::encryptPassword($password)) {
            SysUserLogLogin::add("密码有误:{$password}", $user->id);
            return self::error('账号或密码有误！');
        }

        $token = uuid();
        SysUserLogLogin::add('登录成功', $user->id, $token);
        TokenBiz::add($user->id, $token);

        $u = $user->toArray();
        unset($u['password']);
        unset($u['delete_time']);
        $u['token'] = $token;

        Cache::set(CacheEnum::UID, $user->id);
        Cache::set(CacheEnum::TOKEN, $token);
        return self::success($u);
    }

    public static function logout(): Biz
    {
        $uid = Cache::get(CacheEnum::UID);
        $token = Cache::get(CacheEnum::TOKEN);
        $tokenBiz = TokenBiz::del();
        if ($tokenBiz::hasError()) {
            return $tokenBiz;
        }

        Cache::clear();
        SysUserLogLogin::add('退出登录', $uid, $token);
        return self::success();
    }
}